import 'package:get/get.dart';
import 'package:winkai/db/dao/msg_dao.dart';
import 'package:winkai/db/dao/ses_dao.dart';
import 'package:winkai/helper/msg_receive_helper.dart';
import 'package:winkai/helper/ses_helper.dart';
import 'package:winkai/helper/user_helper.dart';
import 'package:winkai/main.dart';
import 'package:winkai/service/ses_service.dart';
import 'package:winkai/utils/listerer.dart';
import 'package:winkai/widget/empty_layout.dart';

class MsgController extends GetxController {
  factory MsgController() {
    _singleton ??= MsgController._();
    return _singleton!;
  }

  static MsgController? _singleton;

  MsgController._();

  EmptyType? emptyType = EmptyType.loading;

  List<SesInfo> sessionList = [];

  int unreadCount = 0;

  final Dispose _dispose = Dispose();

  @override
  void onInit() {
    super.onInit();
    _initListener();
    refreshData();
  }

  void _initListener() {
    _dispose.add(SesHelper().listen((p0) {
      var (event, sessionInfo) = p0;
      switch (event) {
        case SesEvent.remove:
          sessionList
              .removeWhere((e) => e.session.id == sessionInfo.session.id);
          break;
        case SesEvent.add:
          sessionList.add(sessionInfo);
          _reSort();
          _update();
          break;
        case SesEvent.update:
          sessionList
              .removeWhere((e) => e.session.id == sessionInfo.session.id);
          sessionList.add(sessionInfo);
          _reSort();
          _update();
          break;
        default:
      }
    }));
  }

  Future<void> refreshData() async {
    var res = await getIt<SesService>().selectAll();
    sessionList = res;

    for (var s in res) {
      if (s.message != null) {
        MsgReceiveHelper().checkMsgReplay(
          MsgInfo(msg: s.message!, session: s.session),
        );
      }
    }

    emptyType = null;
    _update();
  }

  /// 重新排序
  void _reSort() {
    sessionList.sort((l, r) {
      var leftTime = l.session.updateTime.millisecondsSinceEpoch;
      var rightTime = r.session.updateTime.millisecondsSinceEpoch;
      if (r.session.isTop) {
        if (!l.session.isTop) {
          return 1;
        } else if (rightTime > leftTime) {
          return 1;
        } else if (rightTime < leftTime) {
          return -1;
        } else {
          return 0;
        }
      } else {
        if (l.session.isTop) {
          return -1;
        } else if (rightTime > leftTime) {
          return 1;
        } else if (rightTime < leftTime) {
          return -1;
        } else {
          return 0;
        }
      }
    });
  }

  Future<void> deleteBySesId(String sessionId) async {
    var item = sessionList
        .firstWhereOrNull((element) => element.session.id == sessionId);
    if (item != null) {
      await delete(item);
    }
  }

  /// 删除会话
  Future<void> delete(SesInfo item) async {
    SesHelper().remove(item);
    await getIt<SesService>().deleteById(item.session.id);
    UserHelper().subtract(item.session.unReadNum);
    refreshData();
  }

  void _update() {
    var unreadCount = 0;
    var items = sessionList;
    for (var item in items) {
      unreadCount = unreadCount + item.unreadCount;
    }
    unreadCount = unreadCount;
    update();
  }

  @override
  void onClose() {
    _dispose.execute();
  }
}
